package com.browsesoft.resource;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.browsesoft.EntityManager;
import com.browsesoft.ManagerGroup;
import com.browsesoft.Tools;
import com.browsesoft.htmlcomponent.HTMLBasicComponent;
import com.browsesoft.htmlcomponent.HTMLTreeComponent;
import com.browsesoft.htmlcomponent.HTMLTreeModel;
import com.browsesoft.noshow.NoShow;
import com.browsesoft.user.Role;
import com.browsesoft.user.User;

/**
 * 分级管理的资源树
 */
public class RightResourceTreeModel implements HTMLTreeModel {
	public RightResourceTreeModel() {
	}

	/**
	 * 拥有的资源
	 */
	public Collection resources = new LinkedList();

	/**
	 * 不拥有的资源
	 */
	public Collection notResources = new HashSet();

	public Collection allResources = new LinkedList();

	/**
	 * 功能树所对应的用户
	 */
	protected Resource root = null;

	/**
	 * 
	 */
	protected HTMLBasicComponent com;

	/**
	 * 不显示设置器
	 */
	private Map nowShowMachines = new HashMap();;

	/**
	 * 初始化model
	 * 
	 * @throws Exception
	 */
	public void init(HttpServletRequest request) throws Exception {
		// 如果有设置不显示配置
		gatherNoShowMachines();
	}

	/**
	 * 收集不显示设置器
	 */
	private void gatherNoShowMachines() {
		try {
			NodeList list = this.com.getPage().getElement()
					.getElementsByTagName("noshow");
			for (int i = 0; i < list.getLength(); i++) {
				Element elem = (Element) list.item(i);
				String className = elem.getAttribute("classname");
				NoShow show = (NoShow) Class.forName(className).newInstance();
				this.nowShowMachines.put(show, elem);
			}
		} catch (InstantiationException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 得到资源
	 * 
	 * @return 资源
	 * @throws Exception
	 */
	public Collection getRes(User user) throws Exception {
		Collection rs = LicensePolicyTool.getRights(user);
		LinkedList link = ((BasicResource) EntityManager.getInstance()
				.getRoot()).getSpecialResByType("role");
		Iterator iter = link.iterator();
		while (iter.hasNext()) {
			Role role = (Role) iter.next();
			LinkedList list = role.getUsers();
			if (list.contains(user)) {
				rs.addAll(LicensePolicyTool.getRights(role));
			}
		}
		return rs;
	}

	/**
	 * 处理用户请求
	 * 
	 * @param request
	 *            客户端请求
	 */
	public void service(HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		User user = (User) request.getSession().getAttribute("loginUser");
		resources = this.getRes(user);
		notResources = ResourceTool.getAllAncenstor(resources);
		this.allResources.addAll(resources);
		this.allResources.addAll(notResources);
		EntityManager entitymanager = (EntityManager) ManagerGroup
				.getManagerGroup().getManager("entity");
		// 装载根资源
		root = entitymanager.getRoot();
		((HTMLTreeComponent) this.com).getExpandNodes().add(root);
		   //不显示过滤
		this.allResources = (LinkedList) filterNoShow();
		
	}
	
	/**
	 * 设置不显示
	 */
	private List filterNoShow()
	{
		List result = new LinkedList();
		result.addAll(this.allResources);
		Iterator iter = this.nowShowMachines.keySet().iterator();
		while(iter.hasNext())
		{
			NoShow show = (NoShow)iter.next();
			Element elem  = (Element) this.nowShowMachines.get(show);
			result = show.filterShow(elem,result,this.com);
		}
		return result;
	}

	/**
	 * 取得根结点
	 * 
	 * @return 根结点
	 */
	public Object getRootNode() throws Exception {
		return root;
	}

	/**
	 * 根据结点返回子结点
	 * 
	 * @return 子结点
	 */
	public LinkedList getChildNodes(Object node) throws Exception {
		LinkedList children = Tools.iteratorToList(((Resource) node)
				.getChildren());
		// 从子中过虑掉无权访问的节点
		children.retainAll(this.allResources);
		return children;
	}

	/**
	 * 根据结点返回结点的名称
	 * 
	 * @return 结点的名称
	 */
	public String getName(Object node) throws Exception {
		return (String) ((Resource) node).getAttributes().get("name");
	}

	/**
	 * 根据结点返回结点的id
	 * 
	 * @return 结点的名称
	 */
	public String getID(Object node) throws Exception {
		return ((Resource) node).getID();
	}

	/**
	 * 根据id找到结点对象
	 * 
	 * @return 结点对象
	 */
	public Object getObject(String ID) throws Exception {
		Iterator iter = this.allResources.iterator();
		while (iter.hasNext()) {
			Resource item = (Resource) iter.next();
			if (item.getID().equals(ID)) {
				return item;
			}
		}
		return null;
	}

	/**
	 * 根据结点返回结点的链接
	 * 
	 * @return 结点的链接
	 */
	public String getLink(Object node) throws Exception {
		return (String) ((Resource) node).getAttributes().get("link");
	}

	/**
	 * 设置模型所对应的组件
	 * 
	 * @param component
	 *            对应的组件
	 */
	public void setComponent(HTMLBasicComponent component) {
		this.com = component;
	}

	/**
	 * 模型更新页面元素
	 * 
	 * @throws Exception
	 */
	public void updatePageElement(HTMLBasicComponent c) throws Exception {
	}

	/**
	 * 设置链接内容
	 * 
	 * @param nodeLink
	 *            链接
	 */
	public void setContextNode(Element nodeLink, Object modelNode)
			throws Exception {
		if (this.notResources.contains(modelNode)) {
			nodeLink.removeAttribute("onclick");
		}
	}

	/**
	 * 判断是否有子
	 */
	public boolean hasChilds(Object obj) {
		Resource res = (Resource) obj;
		return res.getChildren().hasNext();
	}

	/**
	 * 得到节点对应的图标
	 * 
	 * @param node
	 *            节点
	 * @return 图标
	 */
	public String getIcon(Object node) {
		String icon = (String) ((Resource) node).getAttributes().get("f_icon");
		if (icon == null) {
			icon = "fc_default";
		}
		return icon;
	}
}